﻿#include "ChatWin.h"
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QFontDialog>
#include <QDebug>
#include <QTimer>
#include <QDateTime>
#include <QPixmap>
#include <QFontDatabase>
#include <QStyledItemDelegate>
#include <QAbstractItemView>
#include <QScrollBar>
#include <QJsonObject>
#include <QJsonArray>
#include <QKeyEvent>
#include <QTextBlock>
#include <QWebEnginePage>
#include <QTextCharFormat>
#include <QActionGroup>
#include <QMenu>
#include <QColorDialog>
#include <QPainter>

#include "QQCell.h"
#include "global.h"
#include "MainWindow.h"
#include "CustomWidget.h"
#include "capture/widget/capturewidget.h"
#include "EmotionWindow.h"
#include "DataBaseMagr.h"
#pragma execution_character_set("utf-8")
enum{
    MaxLimitTimes = 12,
    MaxLimitSpace = 5
};

ChatWin::ChatWin(QWidget *parent)
    : BaseWindow(parent),
      m_titleBar(&m_MainWin),
      m_mainWgt(&m_MainWin),
      m_leftWgt(&m_MainWin),
      m_rightWgt(&m_MainWin),
      m_midWgt(&m_MainWin),
      //m_webView(&m_MainWin),
      m_FontWidget(&m_MainWin),
      m_fontfamilyCombox(&m_MainWin),
      m_fontsizeCombox(&m_MainWin),
      m_btnBold(&m_MainWin),
      m_btnitalic(&m_MainWin),
      m_btnUnderline(&m_MainWin),
      m_btnColor(&m_MainWin),
      m_btnToolBar(&m_MainWin),
      m_bottomWgt(&m_MainWin),
      m_editMsg(&m_MainWin),
      m_sendWgt(&m_MainWin),
      m_btnClose(&m_MainWin),
      m_btnFont(&m_MainWin),
      m_btnFace(&m_MainWin),
      m_btnFile(&m_MainWin),
      m_btnPicture(&m_MainWin),
      m_btnScreenshot(&m_MainWin),
      m_btnShake(&m_MainWin),
      m_btnHistory(&m_MainWin),
      m_tabWgt(&m_MainWin),
      m_msgMgrWgt(&m_MainWin),
      m_btnFirstPage(&m_MainWin),
      m_btnPrePage(&m_MainWin),
      m_labelTips(&m_MainWin),
      m_btnNextPage(&m_MainWin),
      m_btnLastPage(&m_MainWin),
      m_emotionWgt(nullptr),
      m_bEnterChecked(true),
      m_timer(new QTimer(this)),
      m_nPosition(0),
      m_curPos(QPoint()),
      m_currentPage(0),
      m_totalPage(0),
      m_pChild(nullptr)
{
    this->setAttribute(Qt::WA_DeleteOnClose);
    //加了这个阴影包裹QWebEngineView的widget导致QWebEngineView页面卡死，所以把效果注销了，估计是个bug
    m_MainWin.setGraphicsEffect(nullptr);
    //设置背景色
    this->setAutoFillBackground(true); // 这句要加上, 否则可能显示不出背景图.
    QPalette palette = this->palette();
    palette.setColor(QPalette::Background,QColor("#f0f0f0"));
    this->setPalette(palette);
    this->setMouseTracking(true);
    initUi();
    //initUI();
    initConnect();
}

ChatWin::~ChatWin()
{
    delete m_emotionWgt;
    qDebug() << "ChatWin::~ChatWin()";
}

//设置对应的好友信息数据结构
void ChatWin::setQQCell(QQCellChild *child)
{
    m_pChild = child;
    m_titleBar.m_title.setQQCell(m_pChild);
    m_id = m_pChild->m_id;

    //设置对应child窗体信息
    child->m_pChatWin = this;
    this->UpdateWinInfo();
}

/**
 * @brief ChatWin::InsertChatMsg    插入一条聊天消息
 * @param utcTime                   UTC时间
 * @param font                      字体
 * @param msgText                   聊天正文
 * @param color                     字体颜色
 * @param recv                      标记是接受的消息，还是主动发送的消息
 * @time                            2018/10/26
 */
void ChatWin::InsertChatMsg(uint utcTime, QFont font,const QString& msgText, bool recv, QColor color)
{

    QString msg = const_cast<QString&>(msgText);
    msg.replace("\r","<br />");         //换行替换
    msg.replace("\"","\\\"");           //特殊字符串处理：\" 英文双引号
    //msg.replace(" ","&nbsp;");        //空格字符串处理： 英文双引号,css处理过了，此处不再处理
    QString strTime;
    //显示时间格式
    {
        QDateTime time;
        time.setTime_t(utcTime);

        uint curtime = QDateTime::currentDateTime().toTime_t();

        QTime current_time = QTime::currentTime();
        int hour = current_time.hour();
        int minute = current_time.minute();
        int second = current_time.second();
        int count = hour*3600 + minute*60 + second;

        if(curtime - utcTime > count)
        {
            //不是当天消息
            strTime = time.toString("yyyy-MM-dd hh:mm:ss");
        }else
        {
            //当天消息
            strTime = time.toString("hh:mm:ss");
        }
    }

    //QString strTime = time.toString("yyyy-MM-dd hh:mm:ss");

    //字体
    QString strFont("style=\\\"");
    if(font.underline())
        strFont += QString("text-decoration:underline;");
    if(font.italic())
        strFont += QString("font-style:italic;");
    if(font.bold())
        strFont += QString("font-weight:bold;");
    strFont += "font-family:'" + font.family() + "';";
    int fontSize = font.pointSize();
    if(fontSize < 16)
        fontSize = 16;
    strFont +=QString("font-size:%1pt;").arg(fontSize);
    strFont += QString("\\\"");

    if(recv)
    {
        QString FriendHead = QString("<img src=qrc:/Images/resource/head/%1.png>").arg(m_pChild->m_childInfo.facetype);
        QString html(QString(
        "document.getElementById(\"content\").insertAdjacentHTML(\"beforeEnd\",\"<div class='msg-box'><div class='msg-agent'><div class='agent-avatar'>%1</div><div class='text1'>%2</div><div class='arrow_box_left'><div class='text'><p %4>%3</p></div></div></div></div>\")")
                    .arg( FriendHead )
                    .arg(m_pChild->m_childInfo.nickname + " " +strTime)
                    .arg( msg )
                    .arg(strFont));
        m_pwebView->page()->runJavaScript(html);
        m_pwebView->page()->runJavaScript("window.scrollTo(0,document.body.scrollHeight)");

    }else
    {
        qDebug() << "插入一条消息";
        QString MyHead = QString("<img src=qrc:/Images/resource/head/%1.png width='80px'heigth='80px'>").arg(MainWindow::s_facetype);
        QString html(QString(
        "document.getElementById(\"content\").insertAdjacentHTML(\"beforeEnd\",\"<div class='msg-box'><div class='msg-client'><div class='client-avatar'>%1</div><div class='text2'>%2</div><div class='arrow_box'><div class='text'><p %4>%3</p></div></div></div></div>\")" )
                    .arg( MyHead )
                    .arg( MainWindow::s_strUserNickName + " " +strTime )
                    .arg( msg )
                    .arg(strFont));
        m_pwebView->page()->runJavaScript(html);
        m_pwebView->page()->runJavaScript("window.scrollTo(0,document.body.scrollHeight)");
    }

}

void ChatWin::InsertTipMsg(const QString &msg)
{
    QString html(QString("document.getElementById(\"content\").insertAdjacentHTML(\"beforeEnd\",\"<div class='chat-notice'><span>%1</span></div>\")").arg(msg));
    m_pwebView->page()->runJavaScript(html);
    m_pwebView->page()->runJavaScript("window.scrollTo(0,document.body.scrollHeight)");
}

/**
 * @brief ChatWin::InsertChatMsg    插入一条聊天消息
 * @param utcTime                   UTC时间
 * @param font                      字体
 * @param msgText                   聊天正文
 * @param color                     字体颜色
 * @param recv                      标记是接受的消息，还是主动发送的消息
 * @time                            2018/10/26
 */
void ChatWin::InsertHistoryMsg(uint utcTime, QFont font, const QString &msgText, bool recv, QColor color)
{

    QDateTime time;
    time.setTime_t(utcTime);
    QString strTime = time.toString("yyyy-MM-dd hh:mm:ss");

    //消息抬头
    if(recv)
    {
        m_historyTextedit->setTextColor(Qt::blue);
        m_historyTextedit->setCurrentFont(QFont("黑体",12));
        m_historyTextedit->append(m_pChild->m_childInfo.nickname + " " +strTime);
    }else
    {
        m_historyTextedit->setTextColor(QColor(80,150,100));
        m_historyTextedit->setCurrentFont(QFont("黑体",12));
        m_historyTextedit->append(MainWindow::s_strUserNickName + " " +strTime);
    }

    //消息正文
    m_historyTextedit->setTextColor(color);
    m_historyTextedit->setCurrentFont(font);
    m_historyTextedit->append(msgText);

    //m_historyTextedit->verticalScrollBar()->setValue(m_ChatMsg.verticalScrollBar()->maximum());
}

//开启定时器，抖动窗口
void ChatWin::ShakeWin(const QString &text)
{
    m_nPosition = 0;
    m_curPos = this->pos();
    m_timer->start();
    this->InsertTipMsg(text);
}

void ChatWin::paintEvent(QPaintEvent *)
{
}


void ChatWin::initUi()
{
    QVBoxLayout *midLayout = new QVBoxLayout;
    m_titleBar.m_btnMin.setToolTip("最小化");
    m_titleBar.m_btnExit.setToolTip("退出");
    m_titleBar.m_btnMax.setToolTip("最大化");
    //-------------------------1.聊天消息窗口+字体工具栏布局
    m_pwebView = new QWebEngineView;
    m_pwebView->load(QUrl("qrc:/qss/resource/qss/chatbubble.html"));
    //m_pwebView->load(QUrl("http://qt-project.org/"));
    m_pwebView->setMinimumHeight(400);
    m_pwebView->setMinimumWidth(700);
    m_pwebView->setAutoFillBackground(true);
    m_pwebView->setMouseTracking(true);
    //m_ChatMsg.setReadOnly(true);
    m_pwebView->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
    m_fontfamilyCombox.setFixedSize(100,30);
    m_fontsizeCombox.setFixedSize(50,30);
    //字体Combox初始化
    QFontDatabase database;
    foreach(const QString &family, database.families())
    {
        m_fontfamilyCombox.addItem(family);
    }

    for (int fontsize = 9; fontsize < 50; fontsize++)
    {
        m_fontsizeCombox.addItem(QString::number(fontsize));
    }

    //用于下拉框item的样式美化
    QStyledItemDelegate* itemDelegate = new QStyledItemDelegate();
    m_fontfamilyCombox.setItemDelegate(itemDelegate);
    m_fontsizeCombox.setItemDelegate(itemDelegate);

    m_btnBold.setCheckable(true);
    m_btnitalic.setCheckable(true);
    m_btnUnderline.setCheckable(true);
    m_btnColor.setCheckable(true);
    m_btnBold.setObjectName("ToolBtn");
    m_btnitalic.setObjectName("ToolBtn");
    m_btnUnderline.setObjectName("ToolBtn");
    m_btnColor.setObjectName("ToolBtn");
    m_btnBold.setFixedSize(30,30);
    m_btnitalic.setFixedSize(30,30);
    m_btnUnderline.setFixedSize(30,30);
    m_btnColor.setFixedSize(30,30);
    m_btnColor.setIconSize(QSize(40,40));
    m_btnBold.setIconSize(QSize(40,40));
    m_btnitalic.setIconSize(QSize(40,40));
    m_btnUnderline.setIconSize(QSize(40,40));
    m_btnBold.setIcon(QPixmap(":/Images/resource/midToolBar/Bold.png"));
    m_btnitalic.setIcon(QPixmap(":/Images/resource/midToolBar/Italic.png"));
    m_btnUnderline.setIcon(QPixmap(":/Images/resource/midToolBar/underline.png"));
    m_btnColor.setIcon(QPixmap(":/Images/resource/midToolBar/color.png"));
    m_btnColor.setToolTip("字体颜色");
    m_btnBold.setToolTip("粗体");
    m_btnUnderline.setToolTip("下划线");
    m_btnitalic.setToolTip("斜体");

    m_FontWidget.setMouseTracking(true);
    m_FontWidget.setFixedHeight(40);
    QHBoxLayout *fontLayout = new QHBoxLayout;
    fontLayout->addWidget(&m_fontfamilyCombox);
    fontLayout->addWidget(&m_fontsizeCombox);
    fontLayout->addWidget(&m_btnBold);
    fontLayout->addWidget(&m_btnitalic);
    fontLayout->addWidget(&m_btnUnderline);
    fontLayout->addWidget(&m_btnColor);
    fontLayout->addStretch();
    fontLayout->setSpacing(5);
    fontLayout->setContentsMargins(5,5,5,0);
    m_FontWidget.setLayout(fontLayout);
    m_FontWidget.hide();

    midLayout->setSpacing(0);
    midLayout->setMargin(0);
    midLayout->addWidget(m_pwebView);
    midLayout->addWidget(&m_FontWidget);
    m_midWgt.setMouseTracking(true);
    m_midWgt.setLayout(midLayout);
    m_midWgt.setMinimumHeight(440);
    m_midWgt.setAutoFillBackground(true);
    //字体工具栏初始化设置
    m_editMsg.setFontPointSize(12);
    m_editMsg.setFontFamily("微软雅黑");
    m_font.fontfamily = m_editMsg.fontFamily();
    m_font.pointsize = m_editMsg.fontPointSize();
    m_font.italic = m_editMsg.fontItalic();
    m_font.underline = m_editMsg.fontUnderline();
    m_font.bold = m_editMsg.fontWeight() == QFont::Bold ? true : false;
    qDebug() << m_font.fontfamily << " " << m_font.pointsize << " " << m_font.italic << " " << m_font.underline << " " << m_font.bold;
    //-------------------------2.功能按钮工具栏
    m_btnToolBar.setMouseTracking(true);
    //m_btnToolBar.setFixedHeight(50);
    m_btnFont.setFixedSize(30,30);
    m_btnFace.setFixedSize(30,30);
    m_btnFile.setFixedSize(30,30);
    m_btnPicture.setFixedSize(30,30);
    m_btnScreenshot.setFixedSize(30,30);
    m_btnShake.setFixedSize(30,30);
    m_btnHistory.setFixedSize(30,30);
    m_btnHistory.setCheckable(true);

    m_btnFont.setCheckable(true);
    m_btnFace.setCheckable(true);
    m_btnFont.setToolTip("更改字体");
    m_btnFace.setToolTip("发送表情");
    m_btnFile.setToolTip("发送文件");
    m_btnPicture.setToolTip("发送图片");
    m_btnScreenshot.setToolTip("截屏");
    m_btnShake.setToolTip("发送窗口抖动");
    m_btnHistory.setToolTip("历史消息");
    m_btnFont.setObjectName("ToolBtn");
    m_btnFace.setObjectName("ToolBtn");

    m_btnFile.setObjectName("ToolBtn");
    m_btnPicture.setObjectName("ToolBtn");
    m_btnScreenshot.setObjectName("ToolBtn");
    m_btnShake.setObjectName("ToolBtn");
    m_btnHistory.setObjectName("ToolBtn");

    m_btnFont.setIcon(QPixmap(":/Images/resource/midToolBar/ic_font.png"));
    m_btnFace.setIcon(QPixmap(":/Images/resource/midToolBar/ic_smile.png"));
    m_btnFile.setIcon(QPixmap(":/Images/resource/midToolBar/ic_file.png"));
    m_btnPicture.setIcon(QPixmap(":/Images/resource/midToolBar/ic_picture.png"));
    m_btnScreenshot.setIcon(QPixmap(":/Images/resource/midToolBar/ic_cut.png"));
    m_btnShake.setIcon(QPixmap(":/Images/resource/midToolBar/ic_shake.png"));
    m_btnHistory.setIcon(QPixmap(":/Images/resource/midToolBar/ic_record.png"));

    m_btnFont.setIconSize(QSize(40,40));
    m_btnFace.setIconSize(QSize(40,40));
    m_btnFile.setIconSize(QSize(40,40));
    m_btnPicture.setIconSize(QSize(40,40));
    m_btnScreenshot.setIconSize(QSize(40,40));
    m_btnShake.setIconSize(QSize(40,40));
    m_btnHistory.setIconSize(QSize(40,40));

    QHBoxLayout *toolLayout = new QHBoxLayout;
    toolLayout->addWidget(&m_btnFont);
    toolLayout->addWidget(&m_btnFace);
    toolLayout->addWidget(&m_btnFile);
    toolLayout->addWidget(&m_btnPicture);
    toolLayout->addWidget(&m_btnScreenshot);
    toolLayout->addWidget(&m_btnShake);
    toolLayout->addStretch();
    toolLayout->addWidget(&m_btnHistory);
    toolLayout->setContentsMargins(5,5,5,5);
    m_btnToolBar.setLayout(toolLayout);

    //-------------------------3.发送消息框布局
    m_bottomWgt.setFixedHeight(160);
    m_bottomWgt.setMouseTracking(true);

    m_editMsg.setFixedHeight(100);
    m_editMsg.setFrameShape(QFrame::NoFrame);

    m_btnClose.setObjectName("MsgCloseBtn");
    m_btnSend.setObjectName("MsgSendBtn");
    m_btnAction.setObjectName("MsgSendActionBtn");
    m_sendWgt.setObjectName("MsgSendWgt");
    m_btnClose.setFixedSize(80,35);
    m_btnClose.setText("关闭(&C)");
    m_sendWgt.setFixedSize(115,35);
    m_btnSend.setToolTip("按Enter键发送消息，按Ctrl+Enter键换行");
    m_btnSend.setText("发送(&S)");
    m_btnAction.setFixedSize(35,35);
    m_btnAction.setIcon(QIcon(":/Images/resource/images/indicator_down_white.png"));
    m_btnSend.setFixedSize(80,35);
    QHBoxLayout *sendBtnLyt = new QHBoxLayout;
    sendBtnLyt->setMargin(0);
    sendBtnLyt->setSpacing(0);
    sendBtnLyt->addWidget(&m_btnSend);
    sendBtnLyt->addWidget(&m_btnAction);
    m_sendWgt.setLayout(sendBtnLyt);
    //添加send按钮菜单项
    QMenu *sendMenu = new QMenu(this);
    QAction *actionEnter     = sendMenu->addAction(QIcon(""), tr("按Enter键发送消息"));
    QAction *actionCtrlEnter = sendMenu->addAction(QIcon(""), tr("按Ctrl+Enter键发送消息"));
    connect(actionEnter,&QAction::toggled,this,&ChatWin::SltActionEnter);
    // 设置互斥
    QActionGroup *actionGroup = new QActionGroup(this);
    actionGroup->addAction(actionEnter);
    actionGroup->addAction(actionCtrlEnter);

    // 设置可选
    actionEnter->setCheckable(true);
    actionCtrlEnter->setCheckable(true);

    // 默认配置
    actionEnter->setChecked(true);

    // 设置菜单
    m_btnAction.setMenu(sendMenu);

    // 设置快捷键
    m_btnSend.setShortcut(QKeySequence("alt+s"));
    m_btnClose.setShortcut(QKeySequence("alt+c"));

    QHBoxLayout *bottomBtnLayout = new QHBoxLayout;
    bottomBtnLayout->addStretch();
    bottomBtnLayout->addWidget(&m_btnClose,0,Qt::AlignHCenter);
    bottomBtnLayout->addSpacing(10);
    bottomBtnLayout->addWidget(&m_sendWgt,0,Qt::AlignVCenter);
    bottomBtnLayout->setContentsMargins(0,5,10,5);
    bottomBtnLayout->setSpacing(0);

    QVBoxLayout *bottomLayout = new QVBoxLayout;
    bottomLayout->setMargin(0);
    bottomLayout->setSpacing(0);
    bottomLayout->addWidget(&m_editMsg);
    bottomLayout->addLayout(bottomBtnLayout);
    m_bottomWgt.setLayout(bottomLayout);
    m_bottomWgt.setAutoFillBackground(true); // 这句要加上, 否则可能显示不出背景图.
    QPalette palette = m_bottomWgt.palette();
    palette.setColor(QPalette::Background,Qt::white);
    m_bottomWgt.setPalette(palette);

    //-------------------------5.右侧wiget
    m_msgMgrWgt.setMouseTracking(true);
    m_tabWgt.setMouseTracking(true);
    m_tabWgt.setTabsClosable(true);         //设置标签页可关闭
    m_historyTextedit = new MyTextEdit(&m_tabWgt);
    m_historyTextedit->setReadOnly(true);
    m_historyTextedit->setFrameShape(QFrame::NoFrame);
    m_historyTextedit->hide();
    m_labelTips.setMouseTracking(true);
    m_labelTips.setText("0/0");
    m_labelTips.setAlignment(Qt::AlignCenter);
    m_btnFirstPage.setFixedSize(30,30);
    m_btnPrePage.setFixedSize(30,30);
    m_labelTips.setFixedSize(100,40);
    m_btnNextPage.setFixedSize(30,30);
    m_btnLastPage.setFixedSize(30,30);
    m_btnFirstPage.setObjectName("ToolBtn");
    m_btnPrePage.setObjectName("ToolBtn");
    m_btnNextPage.setObjectName("ToolBtn");
    m_btnLastPage.setObjectName("ToolBtn");
    m_btnFirstPage.setToolTip("第一页");
    m_btnPrePage.setToolTip("上一页");
    m_btnNextPage.setToolTip("下一页");
    m_btnLastPage.setToolTip("最后页");

    m_btnFirstPage.setIcon(QPixmap(":/Images/resource/midToolBar/FirstPage.png"));
    m_btnPrePage.setIcon(QPixmap(":/Images/resource/midToolBar/PrevPage.png"));
    m_btnNextPage.setIcon(QPixmap(":/Images/resource/midToolBar/NextPage.png"));
    m_btnLastPage.setIcon(QPixmap(":/Images/resource/midToolBar/LastPage.png"));
    QHBoxLayout *msgMgrLyout = new QHBoxLayout;
    msgMgrLyout->setMargin(0);
    msgMgrLyout->setSpacing(5);
    msgMgrLyout->addStretch();
    msgMgrLyout->addWidget(&m_btnFirstPage);
    msgMgrLyout->addWidget(&m_btnPrePage);
    msgMgrLyout->addWidget(&m_labelTips);
    msgMgrLyout->addWidget(&m_btnNextPage);
    msgMgrLyout->addWidget(&m_btnLastPage);
    msgMgrLyout->addStretch();
    m_msgMgrWgt.setLayout(msgMgrLyout);

    QVBoxLayout *vtabLayout = new QVBoxLayout;
    vtabLayout->setSpacing(0);
    vtabLayout->setMargin(0);
    vtabLayout->addWidget(&m_tabWgt);
    vtabLayout->addWidget(&m_msgMgrWgt);
    m_rightWgt.setLayout(vtabLayout);
    //-------------------------6.左右两个widget放在一个更大的widget中布局
    m_leftWgt.setMouseTracking(true);
    m_rightWgt.setMouseTracking(true);
    m_mainWgt.setMouseTracking(true);
    m_leftWgt.setAutoFillBackground(true);
    m_rightWgt.setAutoFillBackground(true);
    m_mainWgt.setAutoFillBackground(true);
    m_rightWgt.setPalette(palette);
    m_rightWgt.setFixedWidth(350);
    m_rightWgt.hide();
    QVBoxLayout *comLayout1 = new QVBoxLayout;
    comLayout1->setMargin(0);
    comLayout1->setSpacing(0);
    comLayout1->addWidget(&m_midWgt);
    comLayout1->addWidget(&m_btnToolBar);
    comLayout1->addWidget(&m_bottomWgt);
    m_leftWgt.setLayout(comLayout1);


    QHBoxLayout *comLayout2 = new QHBoxLayout;
    comLayout2->setMargin(0);
    comLayout2->setSpacing(2);  //设置这个为了显示左右两个widget中间的竖灰线
    comLayout2->addWidget(&m_leftWgt);
    comLayout2->addWidget(&m_rightWgt);
    m_mainWgt.setLayout(comLayout2);

    //-------------------------4.整体布局
    Widget* pWin = &m_MainWin;
    QVBoxLayout *vlayout = new QVBoxLayout;
    vlayout->setContentsMargins(0,0,0,0);
    vlayout->setSpacing(0);
    vlayout->addWidget(&m_titleBar);
    vlayout->addWidget(&m_mainWgt);
    pWin->setLayout(vlayout);
    pWin->setMinimumWidth(700);
    this->resize(708,800);

    m_editMsg.installEventFilter(this);

    //表情窗口
    m_emotionWgt = new EmotionWindow();
    m_emotionWgt->show();       //必须先调用一次，否则第一次显示表情窗口的时候，表情窗口高度为0
    m_emotionWgt->hide();
    //
}

void ChatWin::initConnect()
{
    connect(&m_titleBar.m_btnExit,&QPushButton::clicked,this,&ChatWin::SltClose);
    connect(&m_btnClose,&QPushButton::clicked,this,&ChatWin::SltClose);
    connect(&m_titleBar.m_btnMin,&QPushButton::clicked,this,&ChatWin::showMinimized);
    connect(&m_titleBar.m_btnMax,&QPushButton::clicked,this,&ChatWin::SltShowMaxSize);
    connect(&m_btnSend,&QPushButton::clicked,this,&ChatWin::SltSend);
    connect(&m_btnFont,&QToolButton::clicked,this,&ChatWin::SltFontWgtShow);
    connect(&m_btnHistory,&QToolButton::clicked,this,&ChatWin::SltRightWgtShow);
    connect(&m_btnScreenshot,&QToolButton::clicked,this,&ChatWin::SltSreenShot);
    connect(&m_btnShake,&QToolButton::clicked,this,&ChatWin::SltSendWinShake);
    connect(&m_btnFace,&QToolButton::clicked,this,&ChatWin::SltShowNormalEmotionWgt);
    connect(m_emotionWgt,&EmotionWindow::sigclickedFaceid,this,&ChatWin::SltClickedEmotion);
    connect(m_timer,&QTimer::timeout,this,&ChatWin::SltShakeWin);
    m_timer->setInterval(40);
    connect(&m_tabWgt,&QTabWidget::tabCloseRequested,this,&ChatWin::SlttabCloseRequested);
    connect(&m_btnPrePage,&QToolButton::clicked,this,&ChatWin::SltPrePageHistoryMsg);
    connect(&m_btnNextPage,&QToolButton::clicked,this,&ChatWin::SltNextPageHistoryMsg);
    connect(&m_btnFirstPage,&QToolButton::clicked,this,&ChatWin::SltFirstPageHistoryMsg);
    connect(&m_btnLastPage,&QToolButton::clicked,this,&ChatWin::SltLastPageHistoryMsg);
    connect(m_pwebView,&QWebEngineView::loadFinished,this,&ChatWin::SltLoadHistoryMsg);
    //字体widget
    connect(&m_fontfamilyCombox,&QComboBox::currentTextChanged,this,&ChatWin::SltFontFamilyChanged);
    connect(&m_fontsizeCombox,&QComboBox::currentTextChanged,this,&ChatWin::SltFontSizeChanged);
    connect(&m_btnBold,&QToolButton::clicked,this,&ChatWin::SltBoldBtnCLicked);
    connect(&m_btnitalic,&QToolButton::clicked,this,&ChatWin::SltItalicClicked);
    connect(&m_btnUnderline,&QToolButton::clicked,this,&ChatWin::SltUnderlineClicked);
    connect(&m_btnColor,&QToolButton::clicked,this,&ChatWin::SltColorBtnCLicked);
    connect(&m_editMsg,&QTextEdit::currentCharFormatChanged,this,&ChatWin::SltCharFormatChanged);
    //connect(&m_btnFont,&QToolButton::clicked,this,&ChatWin::SltSeleteFont);
}

void ChatWin::SltSeleteFont()
{
    bool ok;
    //m_font = QFontDialog::getFont(&ok, QFont("黑体", 20));
}

//点击截图按钮以后触发槽函数2018/11/12
void ChatWin::SltSreenShot()
{
    CaptureWidget* captureWidget = new CaptureWidget(this);
    captureWidget->show();
}

//点击表情以后触发槽函数2018/11/12
void ChatWin::SltClickedEmotion(int faceid)
{
    m_emotionWgt->close();
    m_btnFace.setChecked(false);
    m_editMsg.SltAddEmotion(faceid);
}

//点击表情按钮2018/11/12
void ChatWin::SltShowNormalEmotionWgt(bool checked)
{
    if(checked)
    {
        QPoint point = m_btnToolBar.mapToGlobal(QPoint(0,0));
        m_emotionWgt->move(point.x(),point.y()-m_emotionWgt->height());
        m_emotionWgt->raise();
        m_emotionWgt->showNormal();
    }else
    {
        m_emotionWgt->close();
    }
}

void ChatWin::closeEvent(QCloseEvent *)
{
    m_emotionWgt->close();
    Q_EMIT sigCloseChatWin(m_id);
}


bool ChatWin::eventFilter(QObject *obj, QEvent *evt)
{
    //回车键发送消息
    if(obj == &m_editMsg)
    {
        if (evt->type() == QEvent::KeyPress)
        {
            QKeyEvent *keyEvent = reinterpret_cast<QKeyEvent *>(evt);
            if( keyEvent->key() == Qt::Key_Return && (keyEvent->modifiers() & Qt::ControlModifier))
            {
                if(m_bEnterChecked)
                {
                    QTextCursor cursor = m_editMsg.textCursor();
                    cursor.insertText("\n");
                    return true;
                }else
                {
                   SltSend();
                   return true;
                }
            }else if(keyEvent->key()==Qt::Key_Return)
            {
                if(m_bEnterChecked)
                {
                    SltSend();
                    return true;
                }else
                {
                    QTextCursor cursor = m_editMsg.textCursor();
                    cursor.insertText("\n");
                    return true;
                }

            }
        }
    }
    return QObject::eventFilter(obj, evt);
}

// 本考虑延迟关闭,但经过在槽函数myhelper::Sleep(1000)测试发现，在同一线程发送信号到槽函数是顺序执行
// 不用担心该窗口先关闭指针已经析构，然后信号到槽再执行导致的野指针问题
void ChatWin::SltClose()
{
    this->close();
    //QTimer::singleShot(1000, this, SLOT(close()));
}

//发送消息打包
/* {"msgType":FMG_MSG_TYPE_WORD,
 *  "time":1540535379,
 *  "clientType":1,
 *  "font":["仿宋",25,0,1,1,1],
 *  "content":[{"msgText":"1"}]}
 * */
void ChatWin::SltSend()
{
    if(MainWindow::s_tcpStatus == DisConnectedHost)
    {
        CMessageBox::Infomation(tr("网络连接已断开，请重新登录"));
        return;
    }
    if(m_editMsg.toPlainText().isEmpty())
    {
        CMessageBox::Infomation(tr("发送内容不能为空！"));
        return;
    }
    //打包需要发送的内容
    QJsonArray content;
    QTextBlock currentBlock = m_editMsg.document()->begin();
    QString InsertMsg;
    while (currentBlock.isValid()) {
        QTextBlock::iterator it;
        for (it = currentBlock.begin(); !(it.atEnd()); ++it) {
            QTextFragment currentFragment = it.fragment();
            if (currentFragment.isValid())
            {
                //qDebug() << currentFragment.charFormat().type();
                QTextCharFormat format = currentFragment.charFormat();
                if(format.isImageFormat())      //TextFragment是图片
                {
                    QRegExp rx("qrc:/face/resource/Face/*.gif");
                    rx.setPatternSyntax(QRegExp::Wildcard);
                    QString&& picName = format.toImageFormat().name();
                    qDebug() << picName;
                    if(rx.exactMatch(picName))      //匹配到系统表情
                    {
                        InsertMsg += QString("<img src=%1>").arg(picName);
                        QRegExp reg1("\\d+.gif");
                        QRegExp reg2(".gif");
                        qDebug() << "表情";
                        int index1 = picName.indexOf(reg1);
                        int index2 = picName.indexOf(reg2);
                        int faceID = picName.mid(index1,index2-index1).toInt();
                        QJsonObject faceid;
                        faceid.insert("faceID",faceID);
                        //FIXME:此处插入一个引用，这个局部变量销毁的时候，这个插入的值会不会有问题？
                        content.append(faceid);
                    }
                    //其他图片暂不处理
                }else               //TextFragment是文字
                {
                    InsertMsg += currentFragment.text();
                    QJsonObject msg;
                    msg.insert("msgText",currentFragment.text());
                    //FIXME:此处插入一个引用，这个局部变量销毁的时候，这个插入的值会不会有问题？
                    content.append(msg);
                }
            }
        }
        currentBlock = currentBlock.next();
        if(currentBlock.isValid())
        {
            InsertMsg += "\r";
            QJsonObject msg;
            msg.insert("msgText","\r");
            content.append(msg);
        }
    }
    //时间
    uint utcTime = QDateTime::currentDateTime().toTime_t();
    //打包字体
    int weight = m_font.bold ? QFont::Bold : QFont::Normal;
    QFont font(m_font.fontfamily,m_font.pointsize,weight,m_font.italic);
    font.setBold(m_font.bold);
    font.setUnderline(m_font.underline);

    QJsonArray fontArray;
    fontArray.append(m_font.fontfamily);
    fontArray.append(m_font.pointsize);
    fontArray.append(0);//颜色暂时只设置为黑色
    fontArray.append(m_font.bold);
    fontArray.append(m_font.italic);
    fontArray.append(m_font.underline);

    QString&& fontToDatabase = QString("%1,%2,%3,%4,%5,%6")
            .arg(m_font.fontfamily).arg(m_font.pointsize).arg(m_font.bold).arg(m_font.italic).arg(m_font.underline).arg(0);
    //打包所有信息
    QJsonObject sendMsg;
    sendMsg.insert("msgType",1);
    sendMsg.insert("time",QJsonValue::fromVariant(utcTime));
    sendMsg.insert("clientType",1);
    sendMsg.insert("font",fontArray);
    sendMsg.insert("content",content);

    Q_EMIT sigSendMsg(sendMsg,m_id);
    //插入到聊天消息显示框
    InsertChatMsg(utcTime,font,InsertMsg,false);
    //testInsert(InsertMsg);
    //插入到数据库
    DataBaseMagr::Instance()->AddHistoryMsg(m_pChild->m_id,0,utcTime,fontToDatabase,InsertMsg);
    //LoadHistoryMsg(1);
    m_editMsg.clear();
}

//发送窗口抖动
void ChatWin::SltSendWinShake()
{
    //本窗口抖动
    this->ShakeWin("☆您发送了一个窗口抖动☆");
    //时间
    uint utcTime = QDateTime::currentDateTime().toTime_t();
    //插入消息
    QJsonArray content;
    QJsonObject msg;
    msg.insert("shake",1);
    content.append(msg);
    //打包所有信息
    QJsonObject sendMsg;
    sendMsg.insert("msgType",1);
    sendMsg.insert("time",QJsonValue::fromVariant(utcTime));
    sendMsg.insert("clientType",1);
    sendMsg.insert("content",content);
    Q_EMIT sigSendMsg(sendMsg,m_id);
}

//发送菜单按钮，选择不同发送内容方式2018/11/12
void ChatWin::SltActionEnter(bool checked)
{
    if(checked)
    {
        m_bEnterChecked = true;
        m_btnSend.setToolTip("按Enter键发送消息，按Ctrl+Enter键换行");
    }else
    {
        m_bEnterChecked = false;
        m_btnSend.setToolTip("按Ctrl+Enter键发送消息，按Enter键换行");
    }
}

//展开字体设置工具栏
void ChatWin::SltFontWgtShow()
{
    if(m_FontWidget.isVisible())
    {
        m_btnFont.setChecked(false);
        m_FontWidget.hide();
    }else
    {
        m_fontfamilyCombox.setCurrentText(m_font.fontfamily);
        m_fontsizeCombox.setCurrentText(QString("%1").arg(m_font.pointsize));
        m_btnBold.setChecked(m_font.bold);
        m_btnitalic.setChecked(m_font.italic);
        m_btnUnderline.setChecked(m_font.underline);
        m_btnFont.setChecked(true);
        m_FontWidget.show();
    }
}

//显示右侧widget(历史消息，文件传输速度等)
void ChatWin::SltRightWgtShow()
{
    if(m_rightWgt.isVisible())
    {
        for(int i = 0;i<m_tabWgt.count();i++)
        {
            m_tabWgt.widget(i)->hide();
            m_tabWgt.removeTab(i);
        }

        //调整widget大小
        m_pwebView->setMinimumWidth(m_pwebView->width());   //不加这个界面会闪动
        this->setMinimumWidth(708);
        m_btnHistory.setChecked(false);
        int width = this->width();
        int height = this->height();
        m_rightWgt.hide();
        this->resize(width-m_rightWgt.width(),height);

    }else
    {

        //显示右侧widget
        m_historyTextedit->show();
        m_tabWgt.insertTab(m_tabWgt.count(),m_historyTextedit,"本地消息");
        m_btnHistory.setChecked(true);
        m_rightWgt.show();
        m_pwebView->setMinimumWidth(m_pwebView->width());
        //调整widget大小
        int width = this->width();
        int height = this->height();
        this->resize(width+m_rightWgt.width(),height);

        this->setMinimumWidth(1060);

        //加载历史消息
        this->SltLastPageHistoryMsg();
    }
    repaint();
}

//粗体
void ChatWin::SltBoldBtnCLicked(bool checked)
{ 
    m_font.bold = checked;
    QFont::Weight weight = checked ? QFont::Bold : QFont::Normal;
    QTextCharFormat fmt;
    fmt.setFontWeight(weight);
    mergeFormatOnWordOrSelection(fmt);
    m_editMsg.setFontWeight(weight);
    m_editMsg.setFocus();

}

//斜体
void ChatWin::SltItalicClicked(bool checked)
{
    m_font.italic = checked;
    QTextCharFormat fmt;
    fmt.setFontItalic(checked);
    mergeFormatOnWordOrSelection(fmt);
    m_editMsg.setFontItalic(checked);
    m_editMsg.setFocus();
}

//下划线
void ChatWin::SltUnderlineClicked(bool checked)
{
    m_font.underline = checked;
    QTextCharFormat fmt;
    fmt.setFontUnderline(checked);
    mergeFormatOnWordOrSelection(fmt);
    m_editMsg.setFontUnderline(checked);
    m_editMsg.setFocus();
}

//更改字体fonfamily
void ChatWin::SltFontFamilyChanged(const QString &fontfamily)
{
    m_font.fontfamily = fontfamily;
    QTextCharFormat fmt;
    fmt.setFontFamily(fontfamily);
    mergeFormatOnWordOrSelection(fmt);
    m_editMsg.setFontFamily(fontfamily);
    m_editMsg.setFocus();
}

//更改字体大小
void ChatWin::SltFontSizeChanged(const QString &fontsize)
{
    m_font.pointsize = fontsize.toInt();
    QTextCharFormat fmt;
    fmt.setFontPointSize(fontsize.toInt());
    mergeFormatOnWordOrSelection(fmt);
    m_editMsg.setFontPointSize(fontsize.toInt());
    m_editMsg.setFocus();
}

void ChatWin::SltColorBtnCLicked(bool checked)
{
    QColorDialog colorDialog;
    QColor color = colorDialog.getColor(m_editMsg.textColor(), this, QStringLiteral("选择字体颜色"));
    m_font.color = color;
    QTextCharFormat fmt;
    fmt.setForeground(color);
    mergeFormatOnWordOrSelection(fmt);
    m_editMsg.setTextColor(color);
    m_editMsg.setFocus();
}

void ChatWin::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
{
    QTextCursor cursor = m_editMsg.textCursor();
    if (!cursor.hasSelection())
        cursor.select(QTextCursor::Document);
    cursor.mergeCharFormat(format);
    m_editMsg.mergeCurrentCharFormat(format);
}

/**
 * @brief ChatWin::LoadHistoryMsg 查询最近的几条聊天记录
 * 载入历史消息：offset == 0 或者offset != 0  且 count ！= 0
 * 载入未读消息：offset == 0,且count != 0,如果为0直接返回
 * 有未读消息的情况，先LoadHistoryMsg(offset,10),再LoadHistoryMsg(0,offset)
 * 没有未读消息的情况，先LoadHistoryMsg(0,10),再LoadHistoryMsg(0,0)
 * @param offset        跳过最近的offset记录
 * @param count         查询的数量
 */
void ChatWin::LoadHistoryMsg(quint8 Type,int offset, int count)
{
    if(0 == count)
        return;
    //获取了好友信息以后插入消息
    if(m_pChild!=NULL)
    {
        QSqlQuery&& query = DataBaseMagr::Instance()->LoadHistoryMsg(m_id,offset,count);
        query.last();
        bool flag = false;
        while(query.isValid() && (count--))
        {
            uint utcTime = query.value(2).toUInt();
            bool recv = query.value(3).toBool();
            QString&& msgText = query.value(5).toString();
            QString&& strfont = query.value(4).toString();
            QStringList fontlist = strfont.split(",");
            QString family = fontlist.at(0);
            int pointSize = fontlist.at(1).toInt();
            bool bold = fontlist.at(2).toInt();
            QFont::Weight w = bold ? QFont::Bold : QFont::Normal;
            bool italic = fontlist.at(3).toInt();
            bool underline = fontlist.at(4).toInt();
            QFont font(family,pointSize,w,italic);
            font.setUnderline(underline);
            this->InsertChatMsg(utcTime,font,msgText,recv);
            query.previous();
            flag = true;
        }
        //只有载入历史消息的时候才需要显示这个，如果是未读消息
        if(flag && (HistoryMsg == Type))
        {
            this->InsertTipMsg("以上为历史消息");
        }
    }
}

//查看所有历史记录 2018/11/18
void ChatWin::LoadAllHistoryMsg()
{
    if(m_pChild!=NULL)
    {
        int numRows = 0;
        m_historyQuery = DataBaseMagr::Instance()->LoadHistoryMsg(m_id);
        m_historyQuery.last();
        numRows = m_historyQuery.at() + 1;
        m_lastPageMsgCnt = numRows % 10;
        if(m_lastPageMsgCnt != 0)
        {
            m_totalPage = numRows/10 + 1;
        }
        else
        {
            m_totalPage = numRows/10;
        }
        m_currentPage = m_totalPage;
    }
}

void ChatWin::GetMsgFromQuery()
{
    int begin = (m_currentPage - 1)*10;
    if(begin>=0)
    {
        m_historyQuery.seek(begin);
        int count = 10;
        while(count-- && m_historyQuery.isValid())
        {
            uint utcTime = m_historyQuery.value(2).toUInt();
            bool recv = m_historyQuery.value(3).toBool();
            QString&& msgText = m_historyQuery.value(5).toString();
            QString&& strfont = m_historyQuery.value(4).toString();
            QStringList fontlist = strfont.split(",");
            QString family = fontlist.at(0);
            int pointSize = fontlist.at(1).toInt();
            bool bold = fontlist.at(2).toInt();
            QFont::Weight w = bold ? QFont::Bold : QFont::Normal;
            bool italic = fontlist.at(3).toInt();
            bool underline = fontlist.at(4).toInt();
            QFont font(family,pointSize,w,italic);
            font.setUnderline(underline);
            this->InsertHistoryMsg(utcTime,font,msgText,recv);
            m_historyQuery.next();
        }
        m_labelTips.setText(QString("%1/%2").arg(m_currentPage).arg(m_totalPage));
    }
}

void ChatWin::testInsert(const QString &msg)
{
    qDebug() << "ChatWin::testInsert(const QString &msg)1";
    QString html = QString("document.getElementById(\"content\").insertAdjacentHTML(\"beforeEnd\",\"<div class='msg-box'><div class='msg-agent'><div class='agent-avatar'>%1</div><div class='text1'>%2</div><div class='arrow_box_left'><div class='text'><p>%3</p></div></div></div></div>\")")
            .arg("<img src=qrc:Images/resource/head/0.png>").arg("李四1111111111111111").arg(msg);
    m_pwebView->page()->runJavaScript(html);
    qDebug() << "ChatWin::testInsert(const QString &msg)2";
    m_pwebView->page()->runJavaScript("window.scrollTo(0,document.body.scrollHeight)");

}

//好友状态改变，更新窗体信息
void ChatWin::UpdateWinInfo()
{
    //更新标题栏信息
    m_titleBar.m_title.updateWinInfo();
    //设置QIcon
    QPixmap pixmap = QPixmap(QString(":/Images/resource/head/%1.png").arg(m_pChild->m_childInfo.facetype));

    if(m_pChild->m_status == STATUS_OFFLINE)
    {
        pixmap = myHelper::ChangeGrayPixmap(pixmap.toImage());
    }

    this->setWindowIcon(QIcon(pixmap));
}

void ChatWin::SltCharFormatChanged(const QTextCharFormat &format)
{
    Q_UNUSED(format);
    QFont::Weight weight = m_font.bold ? QFont::Bold : QFont::Normal;
    m_editMsg.setFontFamily(m_font.fontfamily);
    m_editMsg.setFontPointSize(m_font.pointsize);
    m_editMsg.setFontWeight(weight);
    m_editMsg.setFontItalic(m_font.italic);
    m_editMsg.setFontUnderline(m_font.underline);
    m_editMsg.setTextColor(m_font.color);
}

//抖动窗口
void ChatWin::SltShakeWin()
{
    m_timer->stop();
    if(m_nPosition < MaxLimitTimes)
    {
        ++m_nPosition;
        switch(m_nPosition%4)
        {
        case 1:
        {
            QPoint tmpPos(m_curPos.x(),m_curPos.y()-MaxLimitSpace);
            this->move(tmpPos);
        }
            break;
        case 2:
        {
            QPoint tmpPos(m_curPos.x()-MaxLimitSpace,m_curPos.y()-MaxLimitSpace);
            this->move(tmpPos);
        }
            break;
        case 3:
        {
            QPoint tmpPos(m_curPos.x()-MaxLimitSpace,m_curPos.y());
            this->move(tmpPos);
        }
            break;
        default:
            this->move(m_curPos);
            break;
        }
        m_timer->start();
    }
}

//关闭标签页，2018/11/18
void ChatWin::SlttabCloseRequested(int index)
{
    m_tabWgt.widget(index)->hide();
    m_tabWgt.removeTab(index);

    if(m_tabWgt.count() == 0)
    {
        m_btnHistory.click();
    }
}

//上一页历史消息，每页最多显示10条消息，2018/11/18
void ChatWin::SltPrePageHistoryMsg()
{
    if(m_currentPage <= 1)
        return;
    m_historyTextedit->clear();
    m_currentPage--;
    this->GetMsgFromQuery();
}

//下一页历史消息，每页最多显示10条消息，2018/11/18
void ChatWin::SltNextPageHistoryMsg()
{
    if(m_currentPage >= m_totalPage)
        return;
    m_historyTextedit->clear();
    m_currentPage++;
    this->GetMsgFromQuery();
}

//加载最后一页消息
void ChatWin::SltLastPageHistoryMsg()
{
    this->LoadAllHistoryMsg();
    m_historyTextedit->clear();
    this->GetMsgFromQuery();
}

//加载第一页消息
void ChatWin::SltFirstPageHistoryMsg()
{
    if((m_totalPage < 1) || (1 == m_currentPage) )
        return;
    m_historyTextedit->clear();
    m_currentPage = 1;
    this->GetMsgFromQuery();
}

//实际发现打开窗口速度快于html加载速度，因此等html加载好以后再插入信息
void ChatWin::SltLoadHistoryMsg(bool ok)
{
    if(ok)
    {
        LoadHistoryMsg(HistoryMsg,m_pChild->m_UnReadMsg,10);
        LoadHistoryMsg(UnReadMsg,0,m_pChild->m_UnReadMsg);
        m_pChild->m_UnReadMsg = 0;         //未读消息数清零
    }
    this->activateWindow();
    this->showNormal();
    if(m_pChild->m_bShake)
    {
        this->ShakeWin("☆对方给您发送了一个窗口抖动☆");
        m_pChild->m_bShake = false;
    }
}


